package com.twd.lang.config;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;

public class JedisUtil
{
    // jedis连接池
    private static JedisPool jedisPool;

    private static final String host = "20.6.1.65";

    private static final int port = 6379;

    private static final int timeout = 10000;

    private static final String password = "123456";

    // 默认数据库
    private static final int defaultDatebase = 3;
    // 初始化
    static void init()
    {
        if (jedisPool == null)
        {
            // 配置连接参数
            JedisPoolConfig poolConfig = new  JedisPoolConfig();
            poolConfig.setMaxIdle(200);//最大空闲链接
            poolConfig.setMaxTotal(500);//最大连接数
            poolConfig.setMaxWaitMillis(1000 * 10);//最大等待毫秒数
            poolConfig.setTestOnBorrow(true);//获取链接检查有效性
            poolConfig.setTestOnReturn(false);//返回验证
            poolConfig.setBlockWhenExhausted(true);//链接好近是否阻塞
            poolConfig.setTestOnCreate(true);//部署时 为True;
            try
            {
                jedisPool = new JedisPool(poolConfig, host, port, timeout, password);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    // 获取一个jedis
    private synchronized static Jedis getJedis() {
        return getJedis(defaultDatebase);
    }

    /**
     * 获取一个jedis
     * @param dbIndex 需要操作的数据库索引
     * @return
     */
    private synchronized static Jedis getJedis(int dbIndex) {
        Jedis jedis = null;
        JedisUtil.init();
        if (jedisPool != null) {
            try {
                jedis = jedisPool.getResource();
                jedis.select(dbIndex);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return jedis;
    }

    // 释放redis资源
    private static void releaseResource(Jedis jedis) {
        if (jedis != null) {
            try {
                jedis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取对应key的值
     * @param key redis key
     * @return
     */
    public static String get(String key) {
        return get(key, defaultDatebase);
    }

    /**
     * 获取指定数据库中对应key的值
     * @param key redis key
     * @param dbIndex 数据库索引
     * @return
     */
    public static String get(String key, int dbIndex) {
        Jedis jedis = getJedis(dbIndex);
        if(jedis == null){
            return null;
        }
        try {
            return jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            releaseResource(jedis);
        }
        return null;
    }

    /**
     * 插入数据
     * @param key redis key
     * @param value redis value
     * @param seconds 过期时长(秒)
     * @return
     */
    public synchronized static Boolean save(String key, String value, int seconds) {
        return save(key, value, seconds, defaultDatebase);
    }

    /**
     * 插入数据
     * @param key redis key
     * @param value redis value
     * @param seconds 过期时长(秒)
     * @param dbIndex 数据库索引
     * @return
     */
    public synchronized static Boolean save(String key, String value, int seconds, int dbIndex) {
        Jedis jedis = getJedis(dbIndex);
        if(jedis == null){
            return false;
        }
        try {
            jedis.del(key);
            jedis.set(key, value);
            if (seconds != 0) {
                jedis.expire(key, seconds);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            releaseResource(jedis);
        }
    }

    /**
     *  hash结构-插入一条值
     * @param key - hash空间key
     * @param field - 字段key
     * @param value - 存放对象
     */
    public static void hset(String key, String field, Object value) {
        Jedis jedis = getJedis();
        if(jedis != null){
            try {
                jedis.hset(key.getBytes(), field.getBytes(), serialize(value));
            } catch (Exception e) {
                System.out.println("失败");
            } finally {
                releaseResource(jedis);
            }
        }
    }

    public static void set(String key,  Object value) {
        Jedis jedis = getJedis();
        if(jedis != null){
            try {
                jedis.set(key.getBytes(), serialize(value));
            } catch (Exception e) {
                System.out.println("失败");
            } finally {
                releaseResource(jedis);
            }
        }
    }
    public static byte[] serialize(Object object) throws Exception {
        if (object == null) {
            throw new RuntimeException("{} 对象序列不能为空:" + object);
        }
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            // 序列化
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
            throw new RuntimeException("{} 对象序列化发生了异常!", e);
        } finally {
            // 关闭流
            oos.close();
            baos.close();
        }
    }
    /**
     *
     * hash结构-插入一条值
     * @param key - hash空间key
     * @param field - 字段key
     * @param value - 存放对象
     * @param expire - 失效时间
     */
//    public static void hset(String key, String field, Object value, int expire) {
//        Jedis jedis = getJedis();
//        if(jedis != null){
//            try {
//                jedis.hset(key.getBytes(), field.getBytes(), value.getClass());
//                if (expire != 0) {
//                    jedis.expire(key.getBytes(), expire);
//                }
//            } catch (Exception e) {
//            } finally {
//                releaseResource(jedis);
//            }
//        }
//    }

    /**
     * 删除根据 可以 field删除hash
     * @param key
     * @param field
     * @return
     */
    public static Boolean hdel(String key, String field) {
        Jedis jedis = getJedis();
        if(jedis == null){
            return false;
        }
        try {
            long result = jedis.hdel(key.getBytes(), field.getBytes());
            return result == 1 ? true : false;
        } catch (Exception e) {
            return null;
        } finally {

            releaseResource(jedis);
        }
    }

    /**
     *  从hash结构中取值
     * @param key - hash空间key
     * @param field- 字段key
     * @return Object
     */
    public static Object hget(String key, String field) {
        Jedis jedis = getJedis();
        if(jedis == null){
            return null;
        }
        try {
            byte[] obj = jedis.hget(key.getBytes(), field.getBytes());
            return  obj;
        } catch (Exception e) {
            System.out.println("失败");
        } finally {
            releaseResource(jedis);
        }
        return null;
    }
}